home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / goodies / chromakeymovie / moviecontrol.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  12.4 KB  |  446 lines

  1. /*
  2.     File:        moviecontrol.c
  3.  
  4.     Contains:    
  5.  
  6.     Written by: Jason Hodges-Harris    
  7.  
  8.     Copyright:    Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 7/28/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23. #include <MediaHandlers.h>
  24.  
  25. #ifndef __COLORPICKER__
  26. #include <ColorPicker.h>
  27. #endif
  28.  
  29. #ifndef __MOVIES__
  30. #include <Movies.h>
  31. #endif
  32.  
  33. #ifndef __QDOFFSCREEN__
  34. #include <QDOffscreen.h>
  35. #endif
  36.  
  37. #ifndef __RESOURCES__
  38. #include <Resources.h>
  39. #endif
  40.  
  41. #ifndef __TOOLUTILS__
  42. #include <ToolUtils.h>
  43. #endif
  44.  
  45. #ifndef __TYPES__
  46. #include <Types.h>
  47. #endif
  48.  
  49.  
  50. // Program headers
  51.  
  52. #ifndef __CHROMAPPHEADER__
  53. #include "ChromaKeyMovie.h"
  54. #endif
  55.  
  56.  
  57. //    Global Variables
  58.  
  59.  
  60. /* Global GWorld storage for the QuickTime movie.
  61.    If multiple windows are to be implemented, then these
  62.    declarations should be moved into the window document
  63.    structure, as each movie requires 3 offscreen ports*/
  64.  
  65. GWorldPtr            gOffscreenPort,
  66.                     gBackGroundPort,
  67.                     gBackGroundPicture;
  68. PixMapHandle        gMoviePixmap,
  69.                     gBackGndPixmap,
  70.                     gBackGndPictPM;
  71.  
  72. extern RGBColor        kRGBWhite,
  73.                     kRGBBlack,
  74.                     gKeyColor;
  75.  
  76. extern Boolean        gMovieBackGrnd;
  77. extern Boolean        gDone;
  78. extern Boolean        gMovieOpen;
  79.  
  80.  
  81. /* The PlayMovieChroma() function, is called by Open menu item and
  82.    initialises the movie's offscreen environments and window port  */
  83.  
  84. #pragma segment Test
  85. Boolean    PlayMovieChroma(void)
  86. {
  87.     PicHandle            thePict;
  88.     GDHandle            oldGDev;
  89.     CWindowPtr            oldPort,
  90.                         theWindow;
  91.     MovieDocHndl        theDocHndl;
  92.     OSErr                theError;
  93.     QDErr                error;
  94.     Rect                theRect;
  95.     Fixed                theData = 0xEFFF;
  96.  
  97.     GetGWorld(&oldPort,&oldGDev);
  98.     thePict = GetPicture(rBackGroundPict);                // load the background picture
  99.     theWindow = OpenCWindow();
  100.     theDocHndl=(MovieDocHndl)GetWRefCon((WindowPtr)theWindow);
  101.     HLock((Handle)theDocHndl);
  102.     theError = LoadOneMovie(theDocHndl);                // load a QuickTime movie
  103.     // Check if the QuickTime movie was successfully loaded.
  104.     if (theError)
  105.     {
  106.         if (theError == kappDefErr)
  107.             DisplayAlert (rGenAlert,rErrMessages,1);
  108.         // return gracefully as cancel button selected or load error occurred
  109.         DisposeHandle((Handle)theDocHndl);
  110.         DisposeWindow((WindowPtr)theWindow);
  111.         return false;
  112.     }
  113.     // get movie frame dimensions
  114.     GetMovieBox((**theDocHndl).theMovie,&theRect);
  115.  
  116.     /* create the offscreen GWorlds to store the background image,
  117.        the current movie frame and the composite image for transferring to the screen */
  118.     
  119.     error = NewGWorld(&gOffscreenPort,0,&theRect,nil,nil,0);
  120.     error |= NewGWorld(&gBackGroundPort,0,&theRect,nil,nil,0);
  121.     error |= NewGWorld(&gBackGroundPicture,1,&(**thePict).picFrame,nil,nil,0);
  122.     // Check if the GWorlds created successfully.
  123.     
  124.     if (error != noErr)
  125.     {
  126.         /* failed to allocate GWorlds, Alert user of 
  127.         problem and exit application as can't continue. */
  128.         DisplayAlert (rGenAlert,rErrMessages,2);
  129.         gDone = true;
  130.         return false;
  131.     }
  132.     /* Get the GWorld PixMaps and lock down the offscreen ports. */
  133.     gMoviePixmap = GetGWorldPixMap(gOffscreenPort);
  134.     gBackGndPixmap = GetGWorldPixMap(gBackGroundPort);
  135.     gBackGndPictPM = GetGWorldPixMap(gBackGroundPicture);
  136.     LockPixels(gMoviePixmap);
  137.     LockPixels(gBackGndPixmap);
  138.     LockPixels(gBackGndPictPM);
  139.     SetGWorld(gBackGroundPicture,nil);
  140.     /* Draw PICT resource into its GWorld. This saves time having
  141.        to reload and draw the PICT for each frame. */
  142.     HLock((Handle)thePict);
  143.     DrawPicture(thePict,&(*gBackGroundPicture).portRect);
  144.     HUnlock((Handle)thePict);
  145.     ReleaseResource((Handle)thePict);
  146.     SetGWorld(oldPort,oldGDev);
  147.     /* Create a movie controller for the movie, get the controller
  148.        dimensions  and its port to that of the visible window */
  149.     (**theDocHndl).theController = 
  150.         NewMovieController((**theDocHndl).theMovie,&theRect,mcTopLeftMovie);
  151.     theError = MCGetControllerBoundsRect((**theDocHndl).theController,&theRect);
  152.     theError = MCSetControllerPort((**theDocHndl).theController,(CGrafPtr)theWindow);
  153.     SetMovieGWorld((**theDocHndl).theMovie,gOffscreenPort,nil);
  154.     SizeWindow((WindowPtr)theWindow,theRect.right,theRect.bottom,true);
  155.     SetWTitle((WindowPtr)theWindow,(**theDocHndl).theFileSpec.name);
  156.     ShowWindow((WindowPtr)theWindow);
  157.     gMovieOpen = true;
  158.     HUnlock((Handle)theDocHndl);
  159.     return true;
  160. }
  161.  
  162.  
  163. /* Simple function to load a QuickTime movie and 
  164.    place the reference into the movie window document*/
  165.  
  166. #pragma segment Test
  167. OSErr    LoadOneMovie(MovieDocHndl theDocH)
  168. {
  169.     StandardFileReply    theMovieFile;
  170.     SFTypeList            myTypes = {MovieFileType};
  171.     OSErr                error;
  172.     short                myMovieResFile;
  173.     Boolean                movieChanged;
  174.     
  175.     StandardGetFilePreview(nil,1,myTypes,&theMovieFile);
  176.     if (theMovieFile.sfGood)
  177.     {
  178.         error = OpenMovieFile(&theMovieFile.sfFile,&myMovieResFile,fsRdPerm);
  179.         if (error == noErr)
  180.         {
  181.             (**theDocH).theMovieResID = 0;    // get first movie
  182.             error = NewMovieFromFile(&(**theDocH).theMovie,myMovieResFile,&(**theDocH).theMovieResID,
  183.                             nil,newMovieActive,&movieChanged);
  184.             if(error == noErr)
  185.             {
  186.                 (**theDocH).theFileSpec = theMovieFile.sfFile;
  187.                 CloseMovieFile (myMovieResFile);
  188.                 return noErr;
  189.             }
  190.         }
  191.         return kappDefErr;    // error loading movie
  192.     }
  193.     return -kappDefErr;    // cancel selected
  194. }
  195.  
  196.  
  197. /* When the TransparentColor() function is called,
  198.    it displays the Color Picker and sets the key
  199.    color to the value returned by the Picker */
  200.  
  201. #pragma segment Test
  202. void    TransparentColor()
  203. {
  204.     RGBColor        theNewColor;
  205.     Point            thePoint = {0,0};
  206.     
  207.     // alter the key color if OK selected
  208.     if (GetColor(thePoint,"\pSelect Color",&gKeyColor,&theNewColor))
  209.         gKeyColor = theNewColor;
  210.     return;
  211. }
  212.  
  213.  
  214. /* The SetPlayAllFrames() function is called by the "Play
  215.    every frame" menu item, in the "Movie Options" Menu.
  216.    This calls a movie controller action to */ 
  217.  
  218. #pragma segment Test
  219. Boolean    SetPlayAllFrames(Boolean playAllFrames)
  220. {
  221.     MovieDocHndl    theDocH;
  222.     WindowPtr        theWindow;
  223.     ComponentResult    theResult;
  224.     
  225.     playAllFrames = !playAllFrames;
  226.     if (gMovieOpen)
  227.     {
  228.         theWindow = FrontWindow();
  229.         theDocH = (MovieDocHndl)GetWRefCon(theWindow);
  230.         if (playAllFrames)
  231.             theResult = MCDoAction((**theDocH).theController,mcActionSetPlayEveryFrame,(Ptr)true);
  232.         else
  233.             theResult = MCDoAction((**theDocH).theController,mcActionSetPlayEveryFrame,(Ptr)false);
  234.         if (theResult != noErr)
  235.             DisplayAlert (rGenAlert,rErrMessages,1);
  236.     }
  237.     return playAllFrames;
  238. }
  239.  
  240.  
  241. #pragma segment Test
  242. Boolean    SetLoopMovie(Boolean loopMovie)
  243. {
  244.     MovieDocHndl    theDocH;
  245.     WindowPtr        theWindow;
  246.     ComponentResult    theResult;
  247.     
  248.     loopMovie = !loopMovie;
  249.     if (gMovieOpen)
  250.     {
  251.         theWindow = FrontWindow();
  252.         theDocH=(MovieDocHndl)GetWRefCon(theWindow);
  253.         if (loopMovie)
  254.             theResult = MCDoAction((**theDocH).theController,mcActionSetLooping,(Ptr)true);
  255.         else
  256.             theResult = MCDoAction((**theDocH).theController,mcActionSetLooping,(Ptr)false);
  257.         if (theResult !=noErr)
  258.             DisplayAlert (rGenAlert,rErrMessages,1);
  259.     }
  260.     return loopMovie;
  261. }
  262.  
  263.  
  264. #pragma segment Test
  265. void TransparentKeyMode(WindowPtr theWindow)
  266. {
  267.     MovieDocHndl    theDocHndl;
  268.     CGrafPtr        oldPort;
  269.     GDHandle        oldDevice;
  270.     Rect            theRect;
  271.  
  272.     theRect = (*gOffscreenPort).portRect;
  273.     theDocHndl = (MovieDocHndl)GetWRefCon(theWindow);
  274.     GetGWorld(&oldPort,&oldDevice);
  275.     // use CopyBits()to perform croma keying
  276.     SetGWorld(gBackGroundPort,nil);
  277.     RGBForeColor(&kRGBBlack);
  278.     RGBBackColor(&kRGBWhite);
  279.     CopyBits((BitMap*)(*gBackGndPictPM),
  280.         (BitMap*)(*gBackGndPixmap),
  281.         &(*gBackGroundPicture).portRect,&theRect,srcCopy,nil);
  282.     if (gMovieBackGrnd)
  283.     {
  284.         SetGWorld(gOffscreenPort,nil);
  285.         RGBForeColor(&kRGBBlack);
  286.         RGBBackColor(&gKeyColor);
  287.         CopyBits((BitMap*)(*gBackGndPixmap),
  288.             (BitMap*)(*gMoviePixmap),
  289.             &theRect,&theRect,transparent,nil);
  290.         SetGWorld((CWindowPtr)theWindow,oldDevice);
  291.         RGBForeColor(&kRGBBlack);
  292.         RGBBackColor(&kRGBWhite);
  293.         CopyBits((BitMap*)(*gMoviePixmap),
  294.             (BitMap*)&((*theWindow).portBits),
  295.             &theRect,&theRect,srcCopy,nil);
  296.     }
  297.     else
  298.     {
  299.         SetGWorld(gBackGroundPort,nil);
  300.         RGBForeColor(&kRGBBlack);
  301.         RGBBackColor(&gKeyColor);
  302.         CopyBits((BitMap*)(*gMoviePixmap),
  303.             (BitMap*)(*gBackGndPixmap),
  304.             &theRect,&theRect,transparent,nil);
  305.         SetGWorld((CWindowPtr)theWindow,oldDevice);
  306.         RGBForeColor(&kRGBBlack);
  307.         RGBBackColor(&kRGBWhite);
  308.         CopyBits((BitMap*)(*gBackGndPixmap),
  309.             (BitMap*)&((*theWindow).portBits),
  310.             &theRect,&theRect,srcCopy,nil);
  311.     }
  312.     return;
  313. }
  314.  
  315.  
  316. #pragma segment Test
  317. void ModifierTrackMode(WindowPtr theWindow)
  318. {
  319.     MovieDocHndl                        theDocHndl;
  320.     ModifierTrackGraphicsModeRecord        theModifierStruct;
  321.     long                                theTrackIndex,
  322.                                         theTrackCount;
  323.     Track                                theTrack,
  324.                                         theModifierTrack;
  325.     Media                                theMedia;
  326.     QTAtomContainer                        inputMap;
  327.     QTAtom                                inputAtom;
  328.     OSType                                theMediaType,
  329.                                         inputType;
  330.     short                                resRefNum,
  331.                                         count;
  332.     
  333.     if (gMovieOpen)
  334.     {
  335.         theDocHndl = (MovieDocHndl)GetWRefCon(theWindow);
  336.         SetMovieGWorld((**theDocHndl).theMovie,(CGrafPtr)theWindow,nil);
  337.         theTrackCount = GetMovieTrackCount((**theDocHndl).theMovie);
  338.         theModifierStruct.graphicsMode = transparent;
  339.         theModifierStruct.opColor = gKeyColor;
  340.         theModifierTrack = GetMovieIndTrack((**theDocHndl).theMovie,theTrackCount+1);
  341.         // step thru until first video track found
  342.         for (count=1;count <=theTrackCount;count++)
  343.         {
  344.             theTrack = GetMovieIndTrack((**theDocHndl).theMovie,count);
  345.             theMedia = GetTrackMedia(theTrack);
  346.             GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil);
  347.             if (theMediaType == VideoMediaType)
  348.             {
  349.                 AddTrackReference(theTrack,theModifierTrack,
  350.                                   kTrackModifierTypeGraphicsMode,&theTrackIndex);
  351.                 count = theTrackCount;    // bump track count
  352.             }
  353.             // create and add the input map
  354.             GetMediaInputMap(theMedia,&inputMap);
  355.             QTInsertChild( inputMap, kParentAtomIsContainer, kTrackModifierInput, theTrackIndex,
  356.                   0, 0, nil,&inputAtom);
  357.                   
  358.             QTInsertChild( inputMap, inputAtom, kTrackModifierType, 1, 0, 
  359.                    sizeof(kTrackModifierTypeGraphicsMode), &inputType, nil );
  360.                    
  361.             SetMediaInputMap(theMedia, inputMap );
  362.             QTDisposeAtomContainer(inputMap );
  363.     
  364.         }
  365.         // save changes to movie
  366.         OpenMovieFile(&(**theDocHndl).theFileSpec,&resRefNum,fsRdWrPerm);
  367.         UpdateMovieResource((**theDocHndl).theMovie,resRefNum,(**theDocHndl).theMovieResID,nil);
  368.         CloseMovieFile(resRefNum);
  369.     }
  370.     return;
  371. }
  372.  
  373.  
  374. #pragma segment Test
  375. void VideoGraphicsMode(WindowPtr theWindow, Boolean SetVGM)
  376. {
  377.     MovieDocHndl        theDocHndl;
  378.     long                theTrackCount;
  379.     Media                theMedia;
  380.     Track                movieTrack = nil;
  381.     OSType                theMediaType;
  382.     short                count;
  383.     
  384.     if (gMovieOpen)
  385.     {
  386.         theDocHndl = (MovieDocHndl)GetWRefCon(theWindow);
  387.         SetMovieGWorld((**theDocHndl).theMovie,(CGrafPtr)theWindow,nil);
  388.         theTrackCount = GetMovieTrackCount((**theDocHndl).theMovie);
  389.         for (count=1;count <=theTrackCount;count++)
  390.         {
  391.             movieTrack = GetMovieIndTrack((**theDocHndl).theMovie,count);
  392.             theMedia = GetTrackMedia(movieTrack);
  393.             GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil);
  394.             if (theMediaType == VideoMediaType)
  395.             {
  396.                 if (SetVGM)
  397.                 {
  398.                     if (MediaSetGraphicsMode(GetMediaHandler(theMedia),transparent,&gKeyColor))
  399.                         DisplayAlert (rGenAlert,rErrMessages,1);
  400.                 }
  401.                 else if (!SetVGM)
  402.                 {
  403.                     if (MediaSetGraphicsMode(GetMediaHandler(theMedia),srcCopy,&kRGBWhite))
  404.                         DisplayAlert (rGenAlert,rErrMessages,1);
  405.                 }
  406.             }
  407.         }
  408.     }
  409.     return;
  410. }
  411.  
  412.  
  413. #pragma segment Test
  414. OSErr    DestroyModifierTrack(MovieDocHndl theDocH)
  415. {
  416.     long            theTrackCount;
  417.     Track            theTrack,
  418.                     theModifierTrack;
  419.     Media            theMedia;
  420.     OSType            theMediaType;
  421.     OSErr            theError;
  422.     short            resRefNum,
  423.                     count;
  424.     
  425.     theError = OpenMovieFile(&(**theDocH).theFileSpec,&resRefNum,fsRdWrPerm);
  426.     theTrackCount = GetMovieTrackCount((**theDocH).theMovie);
  427.     theModifierTrack = GetMovieIndTrack((**theDocH).theMovie,theTrackCount);
  428.     theError |= GetMoviesError();
  429.     // step thru until first video track found
  430.     for (count=1;count <=theTrackCount;count++)
  431.     {
  432.         theTrack = GetMovieIndTrack((**theDocH).theMovie,count);
  433.         theMedia = GetTrackMedia(theTrack);
  434.         GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil);
  435.         if (theMediaType == VideoMediaType)
  436.         {
  437.             SetMediaInputMap(theMedia,nil);
  438.             count = theTrackCount;    // bump track count
  439.         }
  440.     }
  441.     theError |= UpdateMovieResource((**theDocH).theMovie,resRefNum,
  442.                                     (**theDocH).theMovieResID,nil);
  443.     CloseMovieFile(resRefNum);
  444.     return theError;
  445. }
  446.